package models;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import com.avaje.ebean.Ebean;
import com.avaje.ebean.Page;
import play.db.ebean.Model;

/**
 * Modele de UtilisateurQcm. Correspond au Passage par un utilisateur d'un QCM.
 * 
 * @author ProjetSI-QCM
 * 
 */
@SuppressWarnings("serial")
@Entity
public class UtilisateurQcm extends Model {
    /**
     * Identifiant UtilisateurQCM.
     */
    @Id
    private Long idUtilisateurQcm;
    /**
     * Reference vers l'Utilisateur.
     */
    private Utilisateur utilisateur;
    /**
     * Reference vers le QCM.
     */
    private Qcm qcm;
    /**
     * Note Obtenue.
     */
    private double note;
    /**
     * Date de passage.
     */
    private Date date;
    /**
     * Duree (en minutes) de l'epreuve.
     */
    private int duree;

    /**
     * Liste des Réponses de l'utilisateur au QCM.
     */
    private List<Choix> listeChoixUtilisateur = new ArrayList<Choix>();

    /**
     * Finder de l'UtilisateurQCM.
     */
    private static Finder<Long, UtilisateurQcm> find = new Finder<Long, UtilisateurQcm>(
            Long.class, UtilisateurQcm.class);

    /**
     * La méthode permet de retrouver un UtilisateurQcm à partir de son ID.
     * 
     * @param id
     *            Identifiant du UtilisateurQcm
     * @return UtilisateurQcm L'objet recherché
     */
    public static UtilisateurQcm findById(final Long id) {
        return Ebean.find(UtilisateurQcm.class, id);
    }

    /**
     * Recherche un UtilisateurQcm en fonction d'un Utilisateur et d'un Qcm.
     * 
     * @param idQcm
     *            Identifiant du Qcm.
     * @param idUtilisateur
     *            Identifiant de l'Utilisateur.
     * @return UtilisateurQcm L'objet recherché.
     */
    public static UtilisateurQcm findByIds(final Long idQcm, final Long idUtilisateur) {
        return find.where().eq("qcm", Qcm.findById(idQcm))
                .eq("utilisateur", Utilisateur.findById(idUtilisateur)).findUnique();
    }

    /**
     * Recherche tous les UtilisateurQcm pour un Qcm.
     * 
     * @param id
     *            Identifiant du Qcm.
     * @return List<UtilisateurQcm> La liste des UtilisateurQcm pour le Qcm donné.
     */
    public static List<UtilisateurQcm> findAllByIdQcm(final Long id) {
        return find.where().eq("qcm", Qcm.findById(id)).findList();
    }

    /**
     * Recherche tous les UtilisateurQcm.
     * 
     * @return List<UtilisateurQcm> Tous les UtilisateurQcm.
     */
    public static List<UtilisateurQcm> findAll() {
        return find.all();
    }

    /**
     * Permet de sauvegarder un UtilisateurQcm en base de données.
     * 
     * @param utilisateurQcm
     *            L'objet à sauvegarder
     */
    public static void create(final UtilisateurQcm utilisateurQcm) {
        utilisateurQcm.save();
    }

    /**
     * Permet de modifier un UtilisateurQcm en base de données.
     * 
     * @param utilisateurQcm
     *            L'objet à modifier.
     */
    public static void update(final UtilisateurQcm utilisateurQcm) {
        utilisateurQcm.update();
    }

    /**
     * Permet de Supprimer un UtilisateurQcm de la base de données.
     * 
     * @param id
     *            L'identifiant du UtilisateurQcm à supprimer.
     */
    public static void delete(final Long id) {
        find.ref(id).delete();
    }

    /**
     * Methode toString.
     * @return La chaine de caractères.
     */
    @Override
    public final String toString() {
        final StringBuffer appdata = new StringBuffer();
        appdata.append("liste des choix :");
        for (Choix choix : listeChoixUtilisateur) {
            appdata.append("\n" + choix.getDescriptifChoix() + "\n");
        }
        return appdata.toString();
    }

    /**
     * Retourne une Page de UtilisateurQcm.
     * 
     * @param page
     *            Page à afficher
     * @param pageSize
     *            Nombre d'objets par page
     * @param sortBy
     *            Propriété utilisée pour le tri
     * @param order
     *            Sens du tri (asc ou desc)
     * @param filter
     *            Filtre appliqué sur le nom de la colonne
     * @return Page<UtilisateurQcm> la page
     */
    public static Page<UtilisateurQcm> page(final int page, final int pageSize,
            final String sortBy, final String order, final String filter) {
        return find.where().ilike("idUtilisateurQcm", "%" + filter + "%")
                .orderBy(sortBy + " " + order).fetch("utilisateur").fetch("qcm")
                .findPagingList(pageSize).setFetchAhead(false).getPage(page);
    }

	/**
	 * @return the idUtilisateurQcm
	 */
	public final Long getIdUtilisateurQcm() {
		return idUtilisateurQcm;
	}

	/**
	 * @param id the idUtilisateurQcm to set
	 */
	public final void setIdUtilisateurQcm(final Long id) {
		this.idUtilisateurQcm = id;
	}

	/**
	 * @return the utilisateur
	 */
	@ManyToOne
	public final Utilisateur getUtilisateur() {
		return utilisateur;
	}

	/**
	 * @param u the utilisateur to set
	 */
	public final void setUtilisateur(final Utilisateur u) {
		this.utilisateur = u;
	}

	/**
	 * @return the qcm
	 */
	@ManyToOne
	public final Qcm getQcm() {
		return qcm;
	}

	/**
	 * @param q the qcm to set
	 */
	public final void setQcm(final Qcm q) {
		this.qcm = q;
	}

	/**
	 * @return the note
	 */
	public final double getNote() {
		return note;
	}

	/**
	 * @param n the note to set
	 */
	public final void setNote(final double n) {
		this.note = n;
	}

	/**
	 * @return the date
	 */
	public final Date getDate() {
		return date;
	}

	/**
	 * @param d the date to set
	 */
	public final void setDate(final Date d) {
		this.date = d;
	}

	/**
	 * @return the duree
	 */
	public final int getDuree() {
		return duree;
	}

	/**
	 * @param d the duree to set
	 */
	public final void setDuree(final int d) {
		this.duree = d;
	}

	/**
	 * @return the listeChoixUtilisateur
	 */
	@ManyToMany(cascade = CascadeType.REMOVE)
	public final List<Choix> getListeChoixUtilisateur() {
		return listeChoixUtilisateur;
	}

	/**
	 * @param l the listeChoixUtilisateur to set
	 */
	public final void setListeChoixUtilisateur(final List<Choix> l) {
		this.listeChoixUtilisateur = l;
	}   

}
